package com.usian.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import com.usian.mapper.AdUserMapper;
import com.usian.model.admin.pojos.AdUser;
import com.usian.model.article.pojos.ApAuthor;
import com.usian.service.CSVToAduserService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
@SuppressWarnings("All")
public class CSVToAduserServiceImpl extends ServiceImpl<AdUserMapper, AdUser> implements CSVToAduserService {
    @Autowired
    private AdUserMapper adUserMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 导出
     *
     * @param response
     * @throws IOException
     */
    @Override
    public void csvTo(HttpServletResponse response) throws IOException {
//        导出压缩文件
        // 导出文件列头
        List<String> titles = Arrays.asList("id", "登录用户名，“登录密码", "盐", "昵称", "头像", "手机号", "状态", "邮箱", "最后一次登陆时间", "创建时间");
        StringBuffer expStr = new StringBuffer();
        ZipOutputStream zos = null;
        OutputStream o = null;
        try {
            //csv文件是逗号分隔，除第一个外，每次写入一个单元格数据后需要输入逗号
            for(String title : titles){
                expStr.append(title).append(",");
            }
            //写完文件头后换行
            expStr.append("\n");
            Integer page=1;
            Integer size=2;
            while (true){
                Page page1 = new Page<>(page,size);
                IPage<AdUser> iPage=page(page1);
                List<AdUser> records = iPage.getRecords();
                if (records.size()==0){
                    break;
                }
                //写内容
                for (AdUser adUser : records) {
                    expStr.append(adUser.getId().toString()).append(",");
                    expStr.append(adUser.getName()).append(",");
                    expStr.append(adUser.getPassword()).append(",");
                    expStr.append(adUser.getSalt()).append(",");
                    expStr.append(adUser.getNickname()).append(",");
                    expStr.append(adUser.getImage()).append(",");
                    expStr.append(adUser.getPhone()).append(",");
                    expStr.append(adUser.getStatus().toString()).append(",");
                    expStr.append(adUser.getEmail()).append(",");
                    expStr.append(SimpleDateFormat.getDateInstance().format(adUser.getLoginTime())).append(",");
                    expStr.append(SimpleDateFormat.getDateInstance().format(adUser.getCreatedTime())).append(",");
                    //写完一行换行
                    expStr.append("\n");
                }
                page=page+1;
            }
            response.setContentType("application/download;charset=UTF-8");
            response.setContentType("Content-type:application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Content-disposition","attachment;filename=" + java.net.URLEncoder.encode("test.zip", "UTF-8"));

            o = response.getOutputStream();
            zos =  new ZipOutputStream(new BufferedOutputStream(o));
            zos.putNextEntry(new ZipEntry("test.zip".replace("zip","csv")));//创建压缩文件内的文件
            zos.write(expStr.toString().getBytes("GBK"));
            zos.closeEntry();
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            if(zos != null){
                zos.close();
            }
            if(o != null){
                o.close();
            }
        }
        return ;
        }






//导出csv文件

        //        使用response对象获取输出流
//        ServletOutputStream outputStream = response.getOutputStream();
//        ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream));
////        设置文件名
//        String filename = "管理员账号.csv";
////        设置头信息
//        response.setHeader("content_disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
////        设置类型
//        response.setContentType("text/csv");
////        response.setContentType("Content-type:application/vnd.ms-excel;charset=UTF-8");
////        创建csv写入对象
//        CSVWriter csvWriter = new CSVWriter(new OutputStreamWriter(outputStream, "utf-8"));
////        写入第一行标题
//        String[] titles = new String[]{"编号", "登录用户名", "登录密码", "昵称", "头像", "手机号", "状态", "邮箱", "最后登录时间", "创建时间"};
//        csvWriter.writeNext(titles);
//
////        设置一个页码
//        int page = 0;
//        int size = 1000;
////        使用死循环进行逐条导出
//        while (true) {
////            查询分页数据
//            List<AdUser> userList = adUserMapper.findPage(page, size);
////           判断集合是否为空，如果为空则跳出死循环
//            if (CollectionUtils.isEmpty(userList)) {
////                这里注意一下是跳出循环体而不是return结束方法
//                break;
//            }
////            遍历分页数据
//            for (AdUser user : userList) {
////                使用csvWriter对象写入对象属性,使用的是writerNext逐条写入
////                而不是使用writerAll全部写入，为了防止数据量过大导致内存泄漏
////                "编号","登录用户名","登录密码","昵称","头像","手机号","状态","邮箱","最后登录时间","创建时间"
//                csvWriter.writeNext(new String[]{String.valueOf(user.getId()), user.getName(), user.getPassword(),
//                        user.getNickname(), user.getImage(), user.getPhone(), String.valueOf(user.getStatus()),
//                        user.getEmail(), new SimpleDateFormat("yyyy-MM-dd").format(user.getLoginTime()),
//                        new SimpleDateFormat("yyyy-MM-dd").format(user.getLoginTime())});
//            }
////            使当前页加加
//            page += size + 1;
//
////            压缩部分
////            String Zipfilename = "账号管理.zip";
////            boolean b = zipSingleFile(filename, Zipfilename);
////            if (b){
////                System.out.println("压缩成功");
////            }else {
////                System.out.println("压缩失败");
////            }
////            释放缓存，防止内存泄漏
//            csvWriter.flush();
//        }
//
////        关闭流
//        csvWriter.close();
//
//    }
//

//
//    public static boolean zipSingleFile(String file, String zipFile) throws IOException {
//
//        boolean bf = true;
//
//        File f = new File(file);
//
//        if (!f.exists()) {
//
//            System.out.println("文件不存在");
//
//            bf = false;
//
//        } else {
//
//            File ff = new File(zipFile);
//
//            if (!f.exists()) {
//
//                ff.createNewFile();
//
//            }
//
//// 创建文件输入流对象
//
//            FileInputStream in = new FileInputStream(file);
//
//// 创建文件输出流对象
//
//            FileOutputStream out = new FileOutputStream(zipFile);
//
//// 创建ZIP数据输出流对象
//
//            ZipOutputStream zipOut = new ZipOutputStream(out);
//
//// 得到文件名称
//
//            String fileName = file.substring(file.lastIndexOf('/') + 1, file.length());
//
//// 创建指向压缩原始文件的入口
//
//            ZipEntry entry = new ZipEntry(fileName);
//
//            zipOut.putNextEntry(entry);
//
//// 向压缩文件中输出数据
//
//            int number = 0;
//
//            byte[] buffer = new byte[512];
//
//            while ((number = in.read(buffer)) != -1) {
//
//                zipOut.write(buffer, 0, number);
//
//            }
//
//            zipOut.close();
//
//            out.close();
//
//            in.close();
//
//        }
//
//        return bf;






    /**
     * 导入csv文件
     */
    @Override
    public Integer csvout(MultipartFile file) throws Exception {
        String charset = "utf-8";
        Reader reader = new InputStreamReader(file.getInputStream(), charset);
//        读取文件路径      后续从前端获取图片路径进行读取
        CSVReader csvReader = new CSVReader(reader);
        String[] strings = new String[]{"编号", "登录用户名", "登录密码", "昵称", "头像", "手机号", "状态", "邮箱", "最后登录时间", "创建时间"};
//        先读取第一行的标题，因为标题不用保存到数据库
//        这里使用逐条读取，不使用读取所有，防止内存泄漏
//        判断是否是模板文件
        String[] titles = csvReader.readNext();
        if (strings.equals(titles)) {
            return 0;
        }
//        初始化一个对象为空
        AdUser adUser = new AdUser();
        Integer i = 0;
//        使用死循环进行读取
        while (true) {
//            进行第二次读取
            String[] contant = csvReader.readNext();
//            判断读取的数据是不是为空，如果为空则跳出循环
            if (contant == null) {
                i = 1;
                break;
            }

//            反之则为对象赋值
            adUser.setId(null);
            adUser.setName(contant[1]);
            adUser.setPassword(contant[2]);
            adUser.setNickname(contant[3]);
            adUser.setImage(contant[4]);
            adUser.setPhone(contant[5]);
            adUser.setSalt(null);
            adUser.setStatus(Integer.valueOf(contant[6]));
            adUser.setEmail(contant[7]);
            adUser.setLoginTime(new SimpleDateFormat("yyyy/MM/dd").parse(contant[8]));
            adUser.setCreatedTime(new SimpleDateFormat("yyyy/MM/dd").parse(contant[9]));
//            添加到redis去重
            Long csv = stringRedisTemplate.opsForSet().add("CSV", JSON.toJSONString(adUser));
            if (csv == 0) {
                System.out.println("以重复数据");
                continue;
            }
            //            根据id查询数据如果查到则退出循环不添加到数据库，如果为空则添加到数据库
            LambdaQueryWrapper<AdUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(AdUser::getName, contant[1]);
            AdUser one = this.getOne(lambdaQueryWrapper);
            if (one != null) {
                continue;
            }
//            添加到数据库中
            this.save(adUser);
            System.out.println(adUser);
        }
        return i;
    }
}
